﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.DataSourcesGDB;
using System.Runtime.InteropServices;

namespace ArgGisUI
{
    public class LayerImporter
    {
        private ManualResetEvent doneEvent;
        public ManualResetEvent DoneEvent
        {
            get { return doneEvent; }
        }
        private ImportLayerInfo[] importLayerInfos;
        private string accessFileName;
        private AutoResetEvent containerThreadAutoEvent;
        public LayerImporter(AutoResetEvent containerThreadAutoEvent, string accessFileName,params ImportLayerInfo[] importLayerInfos)
        {
            this.containerThreadAutoEvent = containerThreadAutoEvent;
            this.accessFileName = accessFileName;  
            this.importLayerInfos = importLayerInfos;
            this.doneEvent = new ManualResetEvent(false);
        }
        private IFeatureWorkspace sourceWorkspace;
        private IFeatureWorkspace targetWorkspace;
        public void Import()
        {
            sourceWorkspace = CreateAccessWorkspace() as IFeatureWorkspace;
            targetWorkspace = CreateSdeWorkspace() as IFeatureWorkspace;
            ((IMultiuserWorkspaceEdit)targetWorkspace).StartMultiuserEditing(esriMultiuserEditSessionMode.esriMESMVersioned);
            foreach (var importLayerInfo in importLayerInfos)
            {
                Import(importLayerInfo);
            }
            try
            {
                ((IWorkspaceEdit)targetWorkspace).StopEditing(true);
            }
            catch (COMException comExc)
            {
                if (comExc.ErrorCode == (int)fdoError.FDO_E_VERSION_REDEFINED)
                {
                    IVersion version = (IVersion)targetWorkspace;
                    string versionName = version.VersionName;
                    IVersionEdit4 versionEdit4 = (IVersionEdit4)targetWorkspace;
                    containerThreadAutoEvent.WaitOne();
                    System.Diagnostics.Trace.Write("Enter");
                    versionEdit4.Reconcile4(versionName, true, true, false, false);
                    ((IWorkspaceEdit)targetWorkspace).StopEditing(true);
                    System.Diagnostics.Trace.WriteLine("  Exit");
                    containerThreadAutoEvent.Set();
                }
                else
                {
                    throw comExc;
                }

            }

            doneEvent.Set();
        }

        private void Import(ImportLayerInfo importLayerInfo)
        {
            ITable sourceTable = sourceWorkspace.OpenTable(importLayerInfo.LayerName);
            int sourceShapeFieldIndex = sourceTable.Fields.FindField("Shape");
            int shapeFieldIndex = sourceTable.FindField("Shape");
        
            ICursor sourceCursor = sourceTable.Search(null, true);
            IRow sourceRow;
            ITable targetTable = targetWorkspace.OpenTable(importLayerInfo.LayerName);
            ((IWorkspaceEdit)targetWorkspace).StartEditOperation();
            int targetShapeFieldIndex = targetTable.Fields.FindField("Shape");
            ICursor targetCursor = targetTable.Insert(true);

            while ((sourceRow = sourceCursor.NextRow()) != null)
            {
                object shape = sourceRow.get_Value(sourceShapeFieldIndex);

                IRowBuffer targetRowBuffer = targetTable.CreateRowBuffer();
                targetRowBuffer.set_Value(targetTable.Fields.FindField("Shape"), shape);
                targetCursor.InsertRow(targetRowBuffer);
            }
            ((IWorkspaceEdit)targetWorkspace).StopEditOperation();
        }


        private void Import(ImportLayerRecordInfo importLayerRecordInfo)
        {
        }

        private IWorkspace CreateAccessWorkspace()
        {
            IPropertySet propertySet = new PropertySetClass();
            propertySet.SetProperty("DATABASE", accessFileName);

            IWorkspaceFactory2 workspaceFactory = new AccessWorkspaceFactoryClass();
            return workspaceFactory.Open(propertySet, 0);
        }

        private IWorkspace CreateSdeWorkspace()
        {
            IPropertySet propertySet = new PropertySetClass();
            propertySet.SetProperty("SERVER", "172.18.6.242");
            propertySet.SetProperty("INSTANCE", "5151");
            propertySet.SetProperty("DATABASE", "sde");
            propertySet.SetProperty("USER", "OS_MTI006_LRZ8LL");
            propertySet.SetProperty("PASSWORD", "OS_MTI006_LRZ8LL");
            propertySet.SetProperty("VERSION", "sde.DEFAULT");
            IWorkspaceFactory2 workspaceFactory = new SdeWorkspaceFactoryClass();
            return workspaceFactory.Open(propertySet, 0);

        }
    }
    public class ImportLayerInfo
    {
        public string LayerName { get; set; }
    }
    public class ImportLayerRecordInfo : ImportLayerInfo
    {
        public int MinObjectId { get; set; }
        public int MaxObjectId { get; set; }
    }
}
